/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.hiof.moraa.server.service;

import com.hiof.moraa.server.dao.AthleteDAO;
import com.hiof.moraa.server.dao.SupportDAO;
import com.hiof.moraa.server.service.model.TypeOfAttendant;
import com.hiof.moraa.server.service.model.LiveLocationFeed;
import com.hiof.moraa.server.service.model.LiveMediaFeed;
import com.hiof.moraa.server.service.model.PassTargetFeed;
import com.hiof.moraa.mapping.TblAthlete;
import com.hiof.moraa.mapping.TblSupport;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 *
 * @author Bergy
 */
public class MessageDeliveryService {

    ObjectMapper mapper = new ObjectMapper();
    SupportDAO supportDAO;
    AthleteDAO athleteDAO;
    BroadcastMessageService broadcastMessageService;

    public void setBroadcastMessageService(BroadcastMessageService broadcastMessageService) {
        this.broadcastMessageService = broadcastMessageService;
    }

    public void setAthleteDAO(AthleteDAO athleteDAO) {
        this.athleteDAO = athleteDAO;
    }

    public void setSupportDAO(SupportDAO supportDAO) {
        this.supportDAO = supportDAO;
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deliveryTargetMessage(int userId, TypeOfAttendant typeOfAttendant, int attendantId, PassTargetFeed passTargetFeed) {
        List<String> buddies = getRelevantUsers(typeOfAttendant, attendantId);
        Map<String, String> messages = new HashMap<String, String>();
        for (String buddy : buddies) {
            //TODO: do convert message here
            messages.put(buddy, getJSonMessage(passTargetFeed));
        }
        //broadcastMessageService.sendMessageToRelevantUser(messages);
        broadcastMessageService.broadcastMessageToBrowser(getJSonMessage(passTargetFeed));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deliveryLiveLocationMessage(int userId, TypeOfAttendant typeOfAttendant, int attendentId, LiveLocationFeed liveLocationFeed) {
        List<String> buddies = getRelevantUsers(typeOfAttendant, attendentId);
        Map<String, String> messages = new HashMap<String, String>();
        for (String buddy : buddies) {
            //TODO: do convert message here
            messages.put(buddy, getJSonMessage(liveLocationFeed));
        }
        //broadcastMessageService.sendMessageToRelevantUser(messages);
        broadcastMessageService.broadcastMessageToBrowser(getJSonMessage(liveLocationFeed));
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public void deliveryLiveMediaMessage(int userId, TypeOfAttendant typeOfAttendant, int attendantId, LiveMediaFeed liveMediaFeed) {
        List<String> buddies = getRelevantUsers(typeOfAttendant, attendantId);
        Map<String, String> messages = new HashMap<String, String>();
        for (String buddy : buddies) {
            //TODO: do convert message here
            messages.put(buddy, getJSonMessage(liveMediaFeed));
        }
        //broadcastMessageService.sendMessageToRelevantUser(messages);
        broadcastMessageService.broadcastMessageToBrowser(getJSonMessage(liveMediaFeed));
    }

    /**
     * This function will return list of username that relevant to userId.
     * @param typeOfAttendant: Athlete or Support
     * @param attendantId: athleteId or supportId
     * @return: List of relevant username   
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public List<String> getRelevantUsers(TypeOfAttendant typeOfAttendant, int attendantId) {
        List<String> result = new ArrayList<String>();
        try {
            if (typeOfAttendant == TypeOfAttendant.ATHLETE) {
                TblAthlete athlete = athleteDAO.getAthleteById(attendantId);
                if (athlete != null) {
                    int teamId = athlete.getTblTeam().getId();

                    List<TblSupport> supports = supportDAO.getTeamMember(teamId);
                    for (TblSupport support : supports) {
                        result.add(support.getTblUser().getUsername());
                    }
                }
            } else if (typeOfAttendant == TypeOfAttendant.SUPPORT) {
                TblSupport support = supportDAO.getSupportById(attendantId);
                if (support != null) {
                    int teamId = support.getTblTeam().getId();

                    List<TblSupport> supports = supportDAO.getTeamMate(attendantId);
                    for (TblSupport teammate : supports) {
                        result.add(teammate.getTblUser().getUsername());
                    }

                    List<TblAthlete> athletes = athleteDAO.getTeamMember(teamId);
                    for (TblAthlete athlete : athletes) {
                        result.add(athlete.getTblUser().getUsername());
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(MessageDeliveryService.class.getName()).log(Level.SEVERE, null, ex);
        }
        return result;
    }

    /**
     * Convert Object to JSON string
     * @param feed
     * @return JSON format
     */
    private String getJSonMessage(Object feed) {
        try {
            return mapper.writeValueAsString(feed);
        } catch (IOException ex) {
            Logger.getLogger(MessageDeliveryService.class.getName()).log(Level.SEVERE, null, ex);
            return null;
        }
    }
}
